package com.iaiai.cobra.redis;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.iaiai.cobra.common.util.JsonUtil;
import com.iaiai.cobra.redis.bean.CacheOnline;
import com.iaiai.cobra.redis.keys.RedisAdminKeys;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Created with RedisAdminCache.
 * Package: com.iaiai.cobra.redis
 * Author: iaiai
 * Create Time: 2024/6/23 13:09
 * QQ: 176291935
 * Email: 176291935@qq.com
 * Description:
 */
@Component
public class RedisOnlineCache {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public static final long loginTimeout = 60 * 30;  //秒，30分钟

    //缓存在线
    public void setOnline(String token,
                          Long userId,
                          String username,
                          String ipv4,
                          String ipAddress,
                          String url) throws Exception {
        CacheOnline cacheOnline = new CacheOnline();
        cacheOnline.setToken(token);
        cacheOnline.setUserId(userId);
        cacheOnline.setDateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        cacheOnline.setIpv4(ipv4);
        cacheOnline.setIpAddress(ipAddress);
        cacheOnline.setUsername(username);
        cacheOnline.setUrl(url);
        String json = JsonUtil.getInstance().serialize(cacheOnline);

        redisTemplate.opsForValue().set(String.format("%s:%s:%s",RedisAdminKeys.onlineUser,userId.toString(),token), json, loginTimeout, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(String.format("%s:%s",RedisAdminKeys.onlineToken,token), json, loginTimeout, TimeUnit.SECONDS);
    }

    //缓存在线
    public void setOnline(CacheOnline cacheOnline) throws Exception {
        if(cacheOnline==null)return;

        cacheOnline.setDateTime(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
        String json = JsonUtil.getInstance().serialize(cacheOnline);

        redisTemplate.opsForValue().set(String.format("%s:%s:%s",RedisAdminKeys.onlineUser,cacheOnline.getUserId().toString(),cacheOnline.getToken()), json, loginTimeout, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(String.format("%s:%s",RedisAdminKeys.onlineToken,cacheOnline.getToken()), json, loginTimeout, TimeUnit.SECONDS);
    }

    //获取在线用户
    public List<CacheOnline> getOnlineByUser(Long userId) throws IOException {
        Set<String> keys = redisTemplate.keys(String.format("%s:%s:*",RedisAdminKeys.onlineUser,userId));
        if(keys==null || keys.size()<=0)return null;

        List<CacheOnline> list = new ArrayList<>();
        Iterator<String> iterable = keys.iterator();
        while(iterable.hasNext()){
            String key = iterable.next();
            String value = redisTemplate.opsForValue().get(key);
            if(StringUtils.isNotEmpty(value)) {
                list.add(JsonUtil.getInstance().deserialize(value,CacheOnline.class));
            }
        }

        return list;
    }

    //获取在线用户
    public CacheOnline getOnlineByToken(String token) throws IOException {
        String json = redisTemplate.opsForValue().get(String.format("%s:%s",RedisAdminKeys.onlineToken,token));
        if(StringUtils.isEmpty(json))return null;

        return JsonUtil.getInstance().deserialize(json,CacheOnline.class);
    }

    //删除
    public void removeOnline(String token,Long userId){
        redisTemplate.delete(String.format("%s:%s:%s",RedisAdminKeys.onlineUser,userId,token));
        redisTemplate.delete(String.format("%s:%s",RedisAdminKeys.onlineToken,token));
    }

    //删除
    public void removeOnline(Long userId) throws IOException {
        List<CacheOnline> cacheOnlines = getOnlineByUser(userId);
        if(cacheOnlines!=null && cacheOnlines.size()>0){
            for (CacheOnline cacheOnline : cacheOnlines) {
                redisTemplate.delete(String.format("%s:%s:%s",RedisAdminKeys.onlineUser,userId,cacheOnline.getToken()));
                redisTemplate.delete(String.format("%s:%s",RedisAdminKeys.onlineToken,cacheOnline.getToken()));
            }
        }
    }

    //分页
    public Page<CacheOnline> findKeysForPage(int page, int size) throws IOException {
        // 计算偏移量
        int offset = (page - 1) * size;

        // 获取所有匹配前缀的键
        Set<String> keys = redisTemplate.keys(String.format("%s:*",RedisAdminKeys.onlineToken));
        List<String> keysPage = keys.stream()
                .skip(offset)
                .limit(size)
                .collect(Collectors.toList());

        // 获取总数，用于构建Page对象
        long total = keys.size();

        List<CacheOnline> list = new ArrayList<>();
        if(keysPage!=null && keysPage.size()>0){
            for (String s : keysPage) {
                String json = redisTemplate.opsForValue().get(s);
                if(StringUtils.isEmpty(json))return null;

                list.add(JsonUtil.getInstance().deserialize(json,CacheOnline.class));
            }
        }

        // 根据查询结果构建Page对象
        Page<CacheOnline> cacheOnlinePage = new Page();
        cacheOnlinePage.setTotal(total);
        cacheOnlinePage.setSize(size);
        cacheOnlinePage.setCurrent(page);
        cacheOnlinePage.setRecords(list);
        return cacheOnlinePage;
    }

}
